import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;


public class LocationManager {
	
	/****************************************
	 * Attributes
	 ****************************************/
	private File inFile;
	private String[] info;
	//private int TOTAL_GROUPS = 22;
	
	
	/****************************************
	 * Constructor
	 ****************************************/
	public LocationManager(String fileName) {
		this.inFile = new File(fileName);
		info = readFile();
	}
	
	
	// Methods
	/****************************************
	 * Get my location
	 ****************************************/
	public Location getMyLocation() {
		Location location = new Location();
		info = readFile(); // Read the file again to make sure location is the latest
		
		location.latitude = Double.parseDouble(info[0]);
		location.longtitude = Double.parseDouble(info[1]);
		location.name = info[2];
		location.address = info[3];
		
		return location;		
	}
	
	
	/****************************************
	 * Share location
	 ****************************************/
	// Share my location
	public void shareMyLocation() {
		MessengerManager mm = new MessengerManager();
		Location location = getMyLocation();
		String message = "";
		
		message += location.latitude + "&&";
		message += location.longtitude + "&&";
		message += location.name + "&&";
		message += location.address;
		
		mm.sendMessage(message);
	}
	
	
	public boolean friendNearBy() {
		MessengerManager mm = new MessengerManager();
		for (int i=1; i<=22; i++) {
			if (i==9) { // Debug
				String temp = mm.getLatestMessage(i);
				String[] temp2 = temp.split("&&");
	
				double lat = Double.parseDouble(temp2[0]);
				double lng = Double.parseDouble(temp2[1]);
	
				if (getMyLocation().distanceTo(lat, lng) < 500) {
					System.out.println("Latest: " + temp);
					return true;
				}
			}
		}
		
		return false;
	}
	
	
	/****************************************
	 * Calculate distance (Meters)
	 ****************************************/
	public double getDistanceBetween(Location location1, Location location2) {
		double latitude1 = location1.latitude;
		double longtitude1 = location1.longtitude;
		double latitude2 = location2.latitude;
		double longtitude2 = location2.longtitude;
		
		double theta = longtitude1 - longtitude2;
		double dist = Math.sin(deg2rad(latitude1)) * Math.sin(deg2rad(latitude2)) + Math.cos(deg2rad(latitude1)) * Math.cos(deg2rad(latitude2)) * Math.cos(deg2rad(theta));
		dist = Math.acos(dist);
		dist = rad2deg(dist);
		dist = dist * 60 * 1.1515; // Miles
		dist = dist * 1.609344; // Km
		dist = dist * 1000; // m
		return dist;
	}
	
	public double getDistanceBetween(double latitude1, double longtitude1, double latitude2, double longtitude2) {
		  double theta = longtitude1 - longtitude2;
		  double dist = Math.sin(deg2rad(latitude1)) * Math.sin(deg2rad(latitude2)) + Math.cos(deg2rad(latitude1)) * Math.cos(deg2rad(latitude2)) * Math.cos(deg2rad(theta));
		  dist = Math.acos(dist);
		  dist = rad2deg(dist);
		  dist = dist * 60 * 1.1515; // Miles
		  dist = dist * 1.609344; // Km
		  dist = dist * 1000; // m
		  return dist;
	}
	
	
	/****************************************
	 * Degree to Radians
	 ****************************************/
	private double deg2rad(double deg) {
	  return (deg * Math.PI / 180.0);
	}

	/****************************************
	 * Radians to Degree
	 ****************************************/
	private double rad2deg(double rad) {
	  return (rad * 180.0 / Math.PI);
	}
	
	
	/****************************************
	 * Read file
	 ****************************************/
	private String[] readFile() {
        File file = inFile;
        BufferedReader reader = null;
        
        int count = 0;
        String[] output = new String[4];

		try {
			reader = new BufferedReader(new FileReader(file));
			String text = null;

			// Repeat until all lines are read
			while ((text = reader.readLine()) != null) {
				// 
				output[count++] = text.toString();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (reader != null) {
					// Close the reader
					reader.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
        
        return output;
	}

}


//----------------
// Location class
//----------------
class Location {
	
	/****************************************
	 * Attributes
	 ****************************************/
	public double latitude;
	public double longtitude;
	public String name;
	public String address;
	
	
	/****************************************
	 * Constructor
	 ****************************************/
	// With all information
	Location(double latitude, double longtitude, String name, String address) {
		this.latitude = latitude;
		this.longtitude = longtitude;
		this.name = name;
		this.address = address;
	}
	
	// Empty Location
	Location() {
		this.latitude = 0;
		this.longtitude = 0;
		this.name = "";
		this.address = "";
	}
	
	
	//Methods
	/****************************************
	 * Calculate distance (Meters)
	 ****************************************/
	public double distanceTo(Location target) {
		double latitude1 = this.latitude;
		double longtitude1 = this.longtitude;
		double latitude2 = target.latitude;
		double longtitude2 = target.longtitude;
		
		double theta = longtitude1 - longtitude2;
		double dist = Math.sin(deg2rad(latitude1)) * Math.sin(deg2rad(latitude2)) + Math.cos(deg2rad(latitude1)) * Math.cos(deg2rad(latitude2)) * Math.cos(deg2rad(theta));
		dist = Math.acos(dist);
		dist = rad2deg(dist);
		dist = dist * 60 * 1.1515; // Miles
		dist = dist * 1.609344; // Km
		dist = dist * 1000; // m
		return dist;
	}
	
	public double distanceTo(double latitude, double longtitude) {
		double latitude1 = this.latitude;
		double longtitude1 = this.longtitude;
		double latitude2 = latitude;
		double longtitude2 = longtitude;
		
		double theta = longtitude1 - longtitude2;
		double dist = Math.sin(deg2rad(latitude1)) * Math.sin(deg2rad(latitude2)) + Math.cos(deg2rad(latitude1)) * Math.cos(deg2rad(latitude2)) * Math.cos(deg2rad(theta));
		dist = Math.acos(dist);
		dist = rad2deg(dist);
		dist = dist * 60 * 1.1515; // Miles
		dist = dist * 1.609344; // Km
		dist = dist * 1000; // m
		return dist;
	}
	
	
	/****************************************
	 * Degree to Radians
	 ****************************************/
	private double deg2rad(double deg) {
	  return (deg * Math.PI / 180.0);
	}

	/****************************************
	 * Radians to Degree
	 ****************************************/
	private double rad2deg(double rad) {
	  return (rad * 180.0 / Math.PI);
	}
}
